use crate::errors::Result;
use crate::rest::client::BinanceRestClient;
use crate::rest::{Account, AccountRaw, BalanceItem, BalanceItemRaw, IncomeRecord, IncomeRecordRaw, LeverageBracket, LeverageBracketRaw, PositionRisk, PositionRiskRaw};
use crate::signer::sign;
use chrono::Utc;

impl BinanceRestClient {
    /// 查询账户信息（含持仓）
    pub async fn get_account(&self) -> Result<Account> {
        let res = self.get("/fapi/v3/account", true).await?;
        let info: AccountRaw = serde_json::from_str(&res)?;
        Ok(info.to_model().unwrap())
    }

    /// GET /fapi/v1/leverageBracket
    pub async fn get_leverage_bracket(
        &self,
        symbol: Option<&str>,
    ) -> Result<Vec<LeverageBracket>> {
        let timestamp = Utc::now().timestamp_millis();
        let mut query_str = format!("timestamp={}", timestamp);
        if let Some(sym) = symbol {
            query_str = format!("symbol={}&{}", sym, query_str);
        }

        let signature = sign(&self.config.secret_key, &query_str);
        let full_query = format!("{}&signature={}", query_str, signature);
        let url = format!("/fapi/v1/leverageBracket?{}", full_query);

        let resp = self.get(&url, true).await?;

        if symbol.is_some() {
            // 单个 symbol 是对象
            let single: LeverageBracketRaw = serde_json::from_str(&resp)?;
            Ok(vec![single.to_model()])
        } else {
            // 全市场是数组
            let list: Vec<LeverageBracketRaw> = serde_json::from_str(&resp)?;
            Ok(list.into_iter().map(|b| b.to_model()).collect())
        }
    }

    /// GET /fapi/v3/balance：查询逐币种账户余额
    pub async fn get_account_balance(&self) -> Result<Vec<BalanceItem>> {
        let timestamp = Utc::now().timestamp_millis();
        let query_str = format!("timestamp={}", timestamp);
        let signature = sign(&self.config.secret_key, &query_str);
        let full_query = format!("{}&signature={}", query_str, signature);
        let url = format!("/fapi/v3/balance?{}", full_query);

        let resp = self.get(&url, true).await?;

        let raws: Vec<BalanceItemRaw> = serde_json::from_str(&resp)?;
        let models: Vec<BalanceItem> = raws.into_iter().filter_map(|r| r.to_model()).collect();
        Ok(models)
    }

    /// GET /fapi/v1/income：收益明细（手续费、强平、返佣等）
    pub async fn get_income_history(
        &self,
        symbol: Option<&str>,
        income_type: Option<&str>,
        start_time: Option<u64>,
        end_time: Option<u64>,
        limit: Option<u32>,
        page: Option<u32>,
    ) -> Result<Vec<IncomeRecord>> {
        let timestamp = Utc::now().timestamp_millis();
        let mut query = vec![format!("timestamp={}", timestamp)];

        if let Some(s) = symbol {
            query.push(format!("symbol={}", s));
        }
        if let Some(t) = income_type {
            query.push(format!("incomeType={}", t));
        }
        if let Some(st) = start_time {
            query.push(format!("startTime={}", st));
        }
        if let Some(et) = end_time {
            query.push(format!("endTime={}", et));
        }
        if let Some(l) = limit {
            query.push(format!("limit={}", l));
        }
        if let Some(p) = page {
            query.push(format!("page={}", p));
        }

        let query_str = query.join("&");
        let signature = sign(&self.config.secret_key, &query_str);
        let url = format!(
            "/fapi/v1/income?{}&signature={}", query_str, signature
        );

        let resp = self.get(&url, true).await?;

        let raws: Vec<IncomeRecordRaw> = serde_json::from_str(&resp)?;
        let models: Vec<IncomeRecord> = raws.into_iter().filter_map(|r| r.to_model()).collect();
        Ok(models)
    }

}
